home *** CD-ROM | disk | FTP | other *** search
- #include <DialogMgr.h>
- #include <ControlMgr.h>
- #include <FileMgr.h>
- #include "HexDump.h"
-
- #define FINDBUFSIZE 2048
-
- Handle findBufH;
- long fBegin;
-
- static DialogPtr dp;
- static Str255 findString;
- static Str255 displayString = "";
- static long fBufFirst;
-
- static struct find_record {
- enum { Hex, ASCII } findBy;
- Boolean fromBeginning;
- Boolean ignoreCase;
- } fParms = { ASCII, true, false };
-
- extern long sBegin;
- extern int fileRef;
- extern long fileSize;
- extern Cursor wait;
-
- doFind()
- {
- if (Conduct_Find_Dialog()) {
- doUpdate();
- fBegin = -1;
- fBufFirst = -1;
- doFindAgain();
- }
- }
-
- doFindAgain()
- {
- long delta, new, max;
- GrafPtr savePort;
-
- SetCursor(&wait);
- if (find(findString)) {
- New_Select(fBegin, fBegin + findString[0]);
- Show_Point(fBegin);
- }
- else SysBeep(10);
- InitCursor();
- }
-
- /* Find Dialog Item Numbers: */
- #define OK 1
- #define CANCEL 2
- #define FINDSTRING 3
- #define FINDHEX 4
- #define FINDASCII 5
- #define FROMBEGIN 7
- #define IGNORECASE 8
-
- Init_Find()
- {
- findBufH = NewHandle(FINDBUFSIZE);
- if (!findBufH) {
- ErrorStr("\pNot enough memory for search.");
- return 0;
- }
- return 1;
- }
-
- Conduct_Find_Dialog()
- {
- int item;
- Str255 s;
- Handle stringH;
- Rect box;
- int type;
- struct find_record fNewParms;
-
- fNewParms = fParms;
- dp = GetNewDialog( OwnedResourceID(FIND_DIALOG), 0L, -1L );
- Setup_Dialog();
- do {
- for (;;) {
- ModalDialog( 0L, &item );
- switch (item) {
- case CANCEL:
- DisposDialog(dp);
- return 0;
- case FINDASCII:
- fNewParms.findBy = ASCII;
- Set_Buttons(&fNewParms);
- break;
- case FINDHEX:
- fNewParms.findBy = Hex;
- Set_Buttons(&fNewParms);
- break;
- case FROMBEGIN:
- fNewParms.fromBeginning = !fNewParms.fromBeginning;
- Set_Buttons(&fNewParms);
- break;
- case IGNORECASE:
- fNewParms.ignoreCase = !fNewParms.ignoreCase;
- Set_Buttons(&fNewParms);
- break;
- default: ;
- }
- if (item==OK) break;
- }
- GetDItem( dp, FINDSTRING, &type, &stringH, &box );
- GetIText( stringH, s );
- } while (!valid(s, &fNewParms));
-
- pstrcpy( displayString, s );
- fParms = fNewParms;
- if (fParms.findBy==ASCII) {
- pstrcpy( findString, displayString );
- if (fParms.ignoreCase) to_lower( &findString[1], (int)findString[0] );
- }
- else Hex_to_String( findString, displayString );
-
- DisposDialog(dp);
- return 1;
- }
-
- Set_Buttons(f)
- struct find_record *f;
- {
- int type;
- Rect box;
-
- Handle Aitem, Hitem, Bitem, Citem;
-
- GetDItem(dp, FINDASCII, &type, &Aitem, &box);
- GetDItem(dp, FINDHEX, &type, &Hitem, &box);
- GetDItem(dp, FROMBEGIN, &type, &Bitem, &box);
- GetDItem(dp, IGNORECASE, &type, &Citem, &box);
-
- if (f->findBy==ASCII) {
- SetCtlValue( (ControlHandle)Aitem, 1 );
- SetCtlValue( (ControlHandle)Hitem, 0 );
- HiliteControl( (ControlHandle)Citem, 0 );
- }
- else {
- SetCtlValue( (ControlHandle)Aitem, 0 );
- SetCtlValue( (ControlHandle)Hitem, 1 );
- HiliteControl( (ControlHandle)Citem, 255 );
- }
- if (f->fromBeginning)
- SetCtlValue( (ControlHandle)Bitem, 1 );
- else
- SetCtlValue( (ControlHandle)Bitem, 0 );
- if (f->ignoreCase)
- SetCtlValue( (ControlHandle)Citem, 1 );
- else
- SetCtlValue( (ControlHandle)Citem, 0 );
-
- }
-
- static
- Setup_Dialog()
- {
- int Stype;
- Handle Sitem;
- Rect Sbox;
-
- Set_Buttons(&fParms);
- GetDItem(dp, FINDSTRING, &Stype, &Sitem, &Sbox);
- SetIText(Sitem, displayString);
- SelIText(dp, FINDSTRING, 0, displayString[0]);
- }
-
- static
- valid(s, f)
- register char *s;
- struct find_record *f;
- {
- register int i;
-
- /* if findBy is ASCII, everything is valid */
- /* if findBy is hex, the only valid chars are 0..9, A..F, a..f */
- if (f->findBy==ASCII) return 1;
- for (i=*s++; i>0; --i, ++s) {
- if ((*s>='0')&&(*s<='9')) continue;
- if ((*s>='A')&&(*s<='F')) continue;
- if ((*s>='a')&&(*s<='f')) continue;
- ErrorStr("\pInvalid character in hex search string.");
- return 0;
- }
- return 1;
- }
-
- static
- Fill_Buffer(filePos)
- long filePos;
- {
- long count = FINDBUFSIZE;
-
- SetFPos( fileRef, fsFromStart, filePos );
- FSRead( fileRef, &count, *findBufH );
- if (fParms.ignoreCase) to_lower( *findBufH, (int)count );
- }
-
- static
- find()
- {
- long start;
- long found;
-
- if (!findString[0]) {
- ErrorStr("\pThere is no search string!");
- return 0;
- }
- if (fBufFirst<0) { /* find... */
- if (fParms.fromBeginning)
- Fill_Buffer(fBufFirst = 0L);
- else
- Fill_Buffer(fBufFirst = sBegin+1);
- start = 0;
- }
- else if ((sBegin+1<fBufFirst) ||
- ((sBegin+findString[0])>=(fBufFirst+FINDBUFSIZE)) ) {
- Fill_Buffer(fBufFirst = sBegin+1);
- start = 0;
- }
- else start = sBegin + 1 - fBufFirst;
-
- do {
- if ( (found = Munger( findBufH, start,
- &findString[1], (long)findString[0], 0L, 0L))>=0 ) {
- fBegin = found+fBufFirst;
- return 1;
- }
- fBufFirst += FINDBUFSIZE - findString[0];
- if (fBufFirst<fileSize)
- Fill_Buffer(fBufFirst);
- } while (fBufFirst<fileSize);
- return 0;
- }
-
- hexval(c)
- {
- if ((c>='0')&&(c<='9')) return c-'0';
- if ((c>='A')&&(c<='F')) return c-'A'+10;
- if ((c>='a')&&(c<='f')) return c-'a'+10;
- }
-
- Hex_to_String( s1, s2 )
- register char *s1, *s2;
- {
- register int len;
- *s1++ = (*s2+1)/2;
- if ((len = *s2++)%2) {
- *s1++ = hexval(*s2++);
- len -= 1;
- }
- while (len) {
- *s1 = 16*hexval(*s2++);
- *s1++ += hexval(*s2++);
- len -= 2;
- }
- }
-
- to_lower(s,n)
- register char *s;
- register int n;
- {
- for (; n>0; --n,++s)
- if ((*s>='A') && (*s<='Z')) *s -= 'A'-'a';
- }